package com.csnf.order.service.impl;

import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.csnf.order.feign.ProductFeignClient;
import com.csnf.order.service.OrderService;
import com.csnf.pojo.Order;
import com.csnf.pojo.Product;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.util.ArrayList;
import java.util.List;

@Service
public class OrderServiceImpl implements OrderService {


    //远程调用的对象
    @Autowired
    RestTemplate restTemplate;

    @Autowired
    DiscoveryClient discoveryClient;

    @Autowired
    LoadBalancerClient loadBalancerClient;


    @Autowired
    ProductFeignClient productFeignClient;


    @SentinelResource(value = "createOrderService",blockHandler = "createOrderFallback")
    @Override
    public Order createOrder(String userName, Integer productId, Integer count) {
        Order order = new Order();
        order.setId(1);
        order.setUserName(userName);
        //构建商品列表
        //远程调用 商品服务   获取商品信息
//        Product pro = getProductFromRemote(productId);

        //负载均衡远程调用
//        Product pro = getProductFromRemoteWithLoadBalancer(productId);

        //基于注解的负载均衡调用
       // Product pro = getProductFromRemoteWithLoadBalancerAnno(productId);

        //OpenFeign远程调用
        Product pro = productFeignClient.getProductById(productId);

        pro.setCount(count);

        List<Product> lst = new ArrayList<>();
        lst.add(pro);

        order.setProducts(lst);

        order.setTotalPrice(pro.getPrice()*count);

        return order;

    }

    public Order createOrderFallback(String userName, Integer productId, Integer count,
                                     BlockException exception) {
        Order order = new Order();
        order.setUserName("请求被sentinel限制了："+exception.getClass());
        return order;

    }


    //基于注解的负载均衡调用
    public Product getProductFromRemoteWithLoadBalancerAnno(Integer productId) {


        //2，构建url   http://127.0.0.1:8080/product/get

        String url = "http://service-product/product/getProductById?id="+productId;
        System.out.println("远程调用是商品服务："+url);

        // 3，发送远程调用
        Product product = restTemplate.getForObject(url, Product.class);


        return product;

    }




    //负载均衡调用
    public Product getProductFromRemoteWithLoadBalancer(Integer productId) {
        //1，知道 service-product 服务的IP+port
        ServiceInstance instance = loadBalancerClient.choose("service-product");


        //2，构建url   http://127.0.0.1:8080/product/get

        String url = "http://"+instance.getHost()+":"+instance.getPort()+"/product/getProductById?id="+productId;
        System.out.println("远程调用是商品服务："+url);

        // 3，发送远程调用
        Product product = restTemplate.getForObject(url, Product.class);


        return product;

    }




    //远程调用service-product 获取商品信息 RestTemplate
    public Product getProductFromRemote(Integer productId) {
        //1，知道 service-product 服务的IP+port
       ServiceInstance instance =  discoveryClient.getInstances("service-product").get(0);

       //2，构建url   http://127.0.0.1:8080/product/get

       String url = "http://"+instance.getHost()+":"+instance.getPort()+"/product/getProductById?id="+productId;
        System.out.println("远程调用是商品服务："+url);

       // 3，发送远程调用
        Product product = restTemplate.getForObject(url, Product.class);


        return product;

    }


}
